package org.example;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @author shichunyue
 * @date 2025-11-12 16:26
 *
 * 将一个原始的JSON字符串转换为Java对象
 *
 * 我看懂了.就是hobby本身是一个抽象类,它有多个子类.当传递hobbies数组时.数组中的元素,
 * 不知道该序列化为哪一个子类.这个注解就是解决这个问题的.对吧.需要在原来的json中添加
 * 一个额外的"type":"computer"这种信息,而在序列化为对象时,会读取Hobby类注解,依据这个
 * type的值,再决定是具体序列化为哪一个具体的子类
 *
 * 当 ObjectMapper 遇到一个抽象类型（如 Hobby）需要反序列化时，它会迷茫：
 * “我该创建哪个具体的子类对象呢？是 PlayComputer 还是 PlayPingPong ？”。
 *
 * 这两个注解的作用就是：
 *
 * 告诉 Jackson：在 JSON 数据里找一个特定的字段，这个字段的值能告诉我们具体应该创建哪种类型的对象。
 * 建立映射关系：将 JSON 中那个特定字段的值，与 Java 中的具体类关联起来。
 *
 * 其实在接收数据反序列化为对象时,我们的pojo中的字段,最好不要用接口或抽象类
 */
public class AppJsonDeserializeJson2Object {
    public static void main(String[] args) {
//        这个是原始的json信息,hobbies里面没有包含我们额外添加的信息 "type":"computer" 和 "type":"pingpong".
//        执行会报错
//        String json = "{\"name\":\"张三\",\"age\":30,\"email\":{\"emailName\":\"zs@company.com\",\"desc\":\"工作中常用邮箱\"},\"hobbies\":[{\"hobbyName\":\"打乒乓球\",\"hobbyDesc\":\"打乒乓球是一种身体锻炼\"},{\"hobbyName\":\"玩电脑\",\"hobbyDesc\":\"玩电脑是一种身体锻炼\"}]}";

        //  额外添加了信息 "type":"computer" 和 "type":"pingpong". 执行不会报错
        String json = "{\"name\":\"张三\",\"age\":30,\"email\":{\"emailName\":\"zs@company.com\",\"desc\":\"工作中常用邮箱\"},\"hobbies\":[{\"type\":\"pingpong\",\"hobbyName\":\"打乒乓球\",\"hobbyDesc\":\"打乒乓球是一种身体锻炼\"},{\"type\":\"computer\",\"hobbyName\":\"玩电脑\",\"hobbyDesc\":\"玩电脑是一种身体锻炼\"}]}";
        System.out.println(json);

        // 创建 ObjectMapper 实例 (通常建议作为单例使用)
        ObjectMapper objectMapper = new ObjectMapper();

        try {
            // 将 JSON 字符串反序列化为 User 对象
            Person user = objectMapper.readValue(json, Person.class);

            // 输出结果
            System.out.println(user);
            // 输出: User{name='张三', age=30, emailAddress='zhangsan@example.com'}

            System.out.println(user.getHobbies()[0].getHobbyName());
            System.out.println(user.getHobbies()[1].getHobbyName());


        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
